package com.learn.grpc.nameserver;

import com.learn.grpc.util.AddressUtil;
import io.grpc.EquivalentAddressGroup;
import io.grpc.NameResolver;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** 自定义 服务实例解析器
 * 1. 继承 io.grpc.NameResolver, 通过 Listener2 更新服务 grpc 维护的实例连接列表
 * 2. 实现自定义 NsNameListener, 当服务实例数量变更时，通知 grpc 更新维护的实例连接
 */
@Slf4j
public class NsNameResolver extends NameResolver implements NsMockNameCenter.ServiceInstanceListener {

    // 服务名
    private String serviceName;

    // grpc 实例列表监听器
    private static Map<String, Listener2> serviceNameMapListener = new HashMap<>();

    public NsNameResolver(String serviceName) {
        this.serviceName = serviceName;
    }

    @Override
    public String getServiceAuthority() {
        return "none";
    }

    @Override
    public void start(Listener2 listener) {

        // 每个服务注册一个监听器
        this.serviceNameMapListener.put(serviceName, listener);

        // 向命名服务器注册实例变更监听器: 监听服务实例变更
        NsMockNameCenter.instance.registerNameListener(this);

        // 初始实例列表
        List<EquivalentAddressGroup> serverList = NsMockNameCenter.instance.getInstanceList(serviceName);
        log.info("地址列表, serviceName:{}, addressList:{}", serviceName.toString(), AddressUtil.getHostPortList(serverList));

        // 初始化通知实例
        this.updateServiceInstances(serviceName, serverList);
    }

    @Override
    public void shutdown() {
        // 清理资源
        this.serviceNameMapListener = null;
    }

    @Override
    public void updateServiceInstances(String serviceName, List<EquivalentAddressGroup> instanceList) {
        // 当服务实例数量发生变更时，通知 grpc 更新实例列表
        serviceNameMapListener.get(serviceName).onResult(ResolutionResult.newBuilder()
                .setAddresses(instanceList)
                .build());
    }


}
